import { Animation, Component, SpriteFrame, _decorator } from "cc";
import { FSM_PARAMS_TYPE_ENUM, PARAM_NAME_ENUM } from "../Enums";
import State from "./State";
import SubStateMachine from "./SubStateMachine";

const {ccclass} = _decorator

type ParamsValueType = boolean | number

export interface IParamValue {
  type: FSM_PARAMS_TYPE_ENUM
  value: ParamsValueType,
}

export const getInitParamTrigger = () => {
  return {
    type: FSM_PARAMS_TYPE_ENUM.TRIGGER,
    value: false,
  }
}

export const getInitParamsNumber = () => {
  return {
    type: FSM_PARAMS_TYPE_ENUM.NUMBER,
    value: 0,
  }
}


@ccclass('StateMachine')
export default abstract class StateMachine extends Component {
  private _currentState: State | SubStateMachine = null
  params: Map<string, IParamValue> = new Map()
  stateMachines: Map<string, SubStateMachine | State> = new Map()
  animationComponent: Animation
  waitingList: Array<Promise<SpriteFrame[]>> = []

  getParams(paramName: string) {
    if (this.params.has(paramName)) {
      return this.params.get(paramName).value
    }
  }

  setParams(paramName: string, value: ParamsValueType) {
    if (this.params.has(paramName)) {
      this.params.get(paramName).value = value
      this.run()
      this.resetTrigger()
    }
  }
  abstract init(): void
  abstract run(): void

  resetTrigger() {
    for (const [, value] of this.params) {
      if (value.type === FSM_PARAMS_TYPE_ENUM.TRIGGER) {
        value.value = false
      }
    }
  }

  get currentState() {
    return this._currentState
  }

  set currentState(newState) {
    if (!newState) {
      return
    }
    this._currentState = newState
    this._currentState.run()
  }
}
